﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace StyleMVVM.Validation
{
	public interface IFluentRule<T> : IValidationRule
	{
		IFluentRule<T> If { get; }

		IFluentRule<T> Then { get; }

		IFluentRule<T> Else { get; }

		IFluentRule<T> And { get; }

		IFluentRule<T> Or { get; }

		IFluentRule<T> When { get; }

		IFluentRule<T> Unless { get; }

		IFluentRule<T> IsNull();

		IFluentRule<T> IsNotNull();

		IFluentRule<T> IsEmpty();

		IFluentRule<T> IsNotEmpty();

		IFluentRule<T> IsTrue();

		IFluentRule<T> IsFalse();

		IFluentRule<T> IsTrueOrNull();

		IFluentRule<T> IsFalseOrNull();

		IFluentRule<T> IsRequired();

		IFluentRule<T> Property<TProp>(Expression<Func<T, TProp>> propertyFunc, string displayName = null);

		IFluentRule<T> Validator<TProp>(Expression<Func<T, TProp>> propertyFunc,
		                                IFluentValidator<TProp> validator,
		                                string displayName = null);

		IFluentRule<T> Method<TReturn>(Expression<Func<T, TReturn>> propertyFunc);

		IIntPropertyOperator<T> IntProperty<TProp>(Expression<Func<T, TProp>> propertyFunc);

		IDoublePropertyOperator<T> DoubleProperty<TProp>(Expression<Func<T, TProp>> propertyFunc);

		IStringPropertyOperator<T> StringProperty<TProp>(Expression<Func<T, TProp>> propertyFunc);

		IFluentRule<T> Value<TValue>(TValue compareValue);

		IFluentRule<T> Value(Func<T, object> compareValue);

		IFluentRule<T> Set<TValue>(params TValue[] paramValues);

		IFluentRule<T> Set<TProp>(params Expression<Func<T, TProp>>[] paramValues);

		IFluentRule<T> Count<TProp>(Expression<Func<T, TProp>> countFunc);

		IFluentRule<T> GreaterThan { get; }

		IFluentRule<T> GreaterThanOrEqualTo { get; }

		IFluentRule<T> LessThan { get; }

		IFluentRule<T> LessThanOrEqualTo { get; }

		IFluentRule<T> EqualTo { get; }

		IFluentRule<T> NotEqualTo { get; }

		IFluentRule<T> Contains { get; }

		IFluentRule<T> IsWarning();

		IFluentRule<T> Message(string message);

		IFluentRule<T> Standard(string standards);
	}
}